using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Office.Server;
using Microsoft.Office.Server.Administration;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint;
using System.Web;
using System.Xml;
using Winsmarts.PI.Common;

namespace PI
{
    class Program
    {
        static void Main(string[] args)
        {
            ProgramInputs inputs = new ProgramInputs(args);

            if (inputs.IsValid)
            {
                try
                {
                    if (
                        Utilities.IsXmlValid(inputs.InputsFile, "Winsmarts.PI.Common.InputsFileSchema.xsd") &
                        Utilities.IsXmlValid(inputs.MappingFile, "Winsmarts.PI.Common.MappingFileSchema.xsd")
                        )
                    {
                        Mappings mappings = new Mappings(inputs.MappingFile);

                        // Begin the import
                        XmlDocument inputDoc = new XmlDocument();
                        inputDoc.Load(inputs.InputsFile);
                        XmlNodeList inputNodes = inputDoc.SelectNodes("./Inputs/Input");

                        int successes = 0;
                        int errors = 0;

                        #region Actual Work

                        using (SPSite site = new SPSite(inputs.SSPURL))
                        {
                            ServerContext context = ServerContext.GetContext(site);
                            UserProfileManager mngr = new UserProfileManager(context);
                            Mapping currentMapping = null;
                            foreach (XmlNode inputNode in inputNodes)
                            {
                                string accountName = inputNode.SelectSingleNode("./" + mappings.AccountField).InnerText;
                                UserProfile profile = mngr.GetUserProfile(accountName);
                                try
                                {
                                    foreach (XmlNode dataNode in inputNode.ChildNodes)
                                    {
                                        currentMapping = mappings[dataNode.Name];

                                        if (currentMapping.MOSSField != "AccountName")
                                        {
                                            if (currentMapping.IsDate)
                                            {
                                                if (dataNode.InnerText.Length != 0)
                                                    profile[currentMapping.MOSSField].Value =
                                                        DateTime.ParseExact(dataNode.InnerText, currentMapping.DateFormat, null);
                                            }
                                            else
                                            {
                                                profile[currentMapping.MOSSField].Value = dataNode.InnerText;
                                            }
                                        }
                                    }
                                    profile.Commit();
                                    successes++;
                                }
                                catch (Exception ex)
                                {
                                    errors++;
                                    Trace.WriteLine("Error Importing:" + accountName + ". Error Details:\n" + ex.ToString(), true);
                                }
                            }
                            Trace.WriteLine("Import Finished, total errors: " + errors + " and total successes: " + successes);
                        }
                        #endregion
                    }
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("Unexpected error occurred:", true);
                    Trace.WriteLine(ex.ToString(), true);
                }
            }
            else
            {
                Trace.WriteLine("Invalid inputs specified", true);
                Trace.PrintHelp();
            }
        }
    }
}